今天的主題:variables
嗯…繼續把他看下去(鳴鳴,星期一)
其實在網路找的專案,我常常找不到某個變數是哪邊生出來的
可能要靠debug印出來看看吧?
有更好的方式嗎?
https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html#looping-over-hashes
以RDBMS的術語來看
多個rows(items),有loop的效果(for...each items),每1個row(key),又能有很多colume(value),的感覺
好東西不用嗎?
- name: with_dict
debug:
msg: "{{ item.key }} - {{ item.value }}"
with_dict: "{{ dictionary }}"
- name: with_dict -> loop (option 1)
debug:
msg: "{{ item.key }} - {{ item.value }}"
loop: "{{ dictionary|dict2items }}" # 可以轉成items
- name: with_dict -> loop (option 2)
debug:
msg: "{{ item.0 }} - {{ item.1 }}"
loop: "{{ dictionary|dictsort }}" # 可以對dict排序一下
參考
https://github.com/paulramsey/ansible
---
sites:
myapp1: # key1
frontend: 80 # value1 # {{ item.value.frontend }}
backend: 80 # value1 # {{ item.value.backend }}
myapp2: # key2
frontend: 80 # value2
backend: 80 # value2
upstream {{ item.key }} {
{% for server in groups.webserver %}
server {{ server }}:{{ item.value.backend }};
{% endfor %}
}
server {
listen {{ item.value.frontend }}; # 沒用with_dict前長這樣 listen 80;
location / {
proxy_pass http://{{ item.key }};
}
}
# ====
# 本來長這樣
upstream demo {{% for server in groups.webserver %} server {{ server }};{% endfor %}}
server { listen 80;
location / { proxy_pass http://demo; }}
- name: activate nginx sites
file: src=/etc/nginx/sites-available/{{ item.key }} dest=/etc/nginx/sites-enabled/{{ item.key }} state=link
with_dict: sites
- name: configure nginx sites
template: src=nginx.conf.j2 dest=/etc/nginx/sites-available/{{ item.key }} mode=0644 # 把j2的template copy到dest
with_dict: sites # 有loop的效果,一個row,又能有很多colume,的感覺
把「variable環境變數」跟「playbook」分離
-環境變數可能比較機密
-一個設計很好的playbook,統一在改環境變數,就能適用在各種環境了
-playbook進版控,環境變數清空,或留預設值供參考
主機清單
可能在/inevntory/hosts.ini
可以寫成ini格式(好像看到專案的都寫ini)
mail.example.com # 你的hosts都有dns的
[webservers]
foo.example.com
bar.example.com
www[01:50].example.com # 也可以用簡單的語言,表示:www01~www50
www-[a:f].example.com # 英文字麻a通!!
[dbservers]
one.example.com
two.example.com
three.example.com
all:
hosts:
mail.example.com:
children:
webservers:
hosts:
foo.example.com:
bar.example.com:
dbservers:
hosts:
one.example.com:
two.example.com:
three.example.com:
在家裡的環境,大部分沒domain name,就是給主機別名aliases,再給static ip
(不要吃dhcp,不然你dhcp要固定這些hosts的mac配給固定ip)
jumper(別名) ansible_port=5555 ansible_host=192.0.2.50 \
ansible_connection=ssh ansible_user=mpdehaan
...
hosts:
jumper:
ansible_port: 5555
ansible_host: 192.0.2.50
[atlanta]
host1 http_port=80 maxRequestsPerChild=808
host2 http_port=303 maxRequestsPerChild=909
The INI way:
[atlanta] # 這個group的主機
host1
host2
[atlanta:vars] # group atlanta的變數
ntp_server=ntp.atlanta.example.com
proxy=proxy.atlanta.example.com
The YAML version:
atlanta:
hosts:
host1:
host2:
vars:
ntp_server: ntp.atlanta.example.com
proxy: proxy.atlanta.example.com
這個也蠻常見的,不難,一定要會
要注意:
yaml格式的冒號「 :」前、後都能放 => :vars、vars:
解決方式:
[atlanta]
host1
host2
[raleigh]
host2
host3
# southeast的小孩
[southeast:children] # groups的groups
atlanta
raleigh
[southeast:vars]
some_server=foo.southeast.example.com
halon_system_timeout=30
self_destruct_countdown=60
escape_pods=2
# usa的小孩
[usa:children]
southeast
northeast
southwest
northwest
# 所以階層就會長這樣
all: # 所有的hosts,永遠是最上層
children:
usa: # 此例中,usa輩份最年長,阿公了
children:
southeast: # 爸爸
children:
atlanta: # 兒子
hosts:
host1:
host2:
raleigh:
hosts:
host2:
host3:
vars: # southeast的變數,atlanta、raleigh都能用
some_server: foo.southeast.example.com
halon_system_timeout: 30
self_destruct_countdown: 60
escape_pods: 2
northeast:
northwest:
southwest:
all:所有的hosts
ungrouped:除了all以外,沒有group的主機
比較偏一定會用到的、希望整個playbook都能用到的參數
這樣的變數會放在這些目錄底下
# 放在/etc/ansible
/etc/ansible/hosts
/etc/ansible/group_vars/raleigh # 各種格式都可以yml、yaml、json
# group raleigh的變數檔內容:
# ---
# ntp_server: acme.example.org # group raleigh的變數
# database_server: storage.example.org # group raleigh的變數
# 也可以group再建目錄(以group raleigh為例)
/etc/ansible/group_vars/raleigh/db_settings
/etc/ansible/group_vars/raleigh/cluster_settings
/etc/ansible/group_vars/webservers
/etc/ansible/host_vars/foosball
# 放在/ansible專案目錄/
/ansible專案目錄/group_vars/all/vars # 這個專案都能用的到的變數
/ansible專案目錄/inventory/group_vars/all.yml # 這些inventory(主機清單)都能用的到的變數
group_vars/和host_vars/可以存在於playbook/或inventory/中
如果兩個目錄都存在,則playbook/中的變數會蓋掉inventory/中的變數
然後再需要的地方引用
#!/bin/bash
#
# Program: Vagrant func and vars
# History: 2017/1/19 Kyle.b Release # 參考K大的kube-ansible專案
GROUP_VARS_PATH="./inventory/group_vars/all.yml"
# 變成GROUP_VARS_PATH,讓playbook使用{{GROUP_VARS_PATH}}
INVENTORY_PATH="./inventory/hosts.ini"
VAGRAN_CONFIG_PATH="./hack/.config.rb"
可能的情境
https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#variable-file-separation
就是把variables寫在一個yaml檔
playbook有需要的時候再去吃它
---
# in the above example, this would be vars/external_vars.yml
somevar: somevalue
password: magic
---
- hosts: all
remote_user: root
vars:
favcolor: blue
vars_files:
- /vars/external_vars.yml # playbook需要的去叫用
tasks:
- name: this is just a placeholder
command: /bin/echo foo
如果你的ansible要更靈活的給第3方工具運用(例如你寫script、或其他自動化工具)
# key-value 格式
$ ansible-playbook release.yml --extra-vars "version=1.23.45 other_variable=foo"
# JSON string format
$ ansible-playbook release.yml --extra-vars '{"version":"1.23.45","other_variable":"foo"}'
$ ansible-playbook arcade.yml --extra-vars '{"pacman":"mrs","ghosts":["inky","pinky","clyde","sue"]}'
# 要小心escaping quotes(所以下指令比較麻煩),不過還是有必須用到的情境
$ ansible-playbook arcade.yml --extra-vars "{\"name\":\"Conan O\'Brien\"}"
$ ansible-playbook arcade.yml --extra-vars '{"name":"Conan O'\\\''Brien"}'
$ ansible-playbook script.yml --extra-vars "{\"dialog\":\"He said \\\"I just can\'t get enough of those single and double-quotes"\!"\\\"\"}"
# YAML string format
$ ansible-playbook release.yml --extra-vars '
version: "1.23.45"
other_variable: foo'
$ ansible-playbook arcade.yml --extra-vars '
pacman: mrs
ghosts:
- inky
- pinky
- clyde
- sue'
# 把json或yaml格式的變數寫在一個檔案
$ ansible-playbook release.yml --extra-vars "@some_file.json"